package router

import (
	"iot-cloud-platform/internal/auth"
	"iot-cloud-platform/internal/services"

	"github.com/gin-gonic/gin"
)

// SetupRoutes configures all API routes
func SetupRoutes(r *gin.Engine, container *services.Container) {
	// Health check
	r.GET("/health", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"status":  "healthy",
			"service": "iot-cloud-platform",
		})
	})

	// API v1 routes
	v1 := r.Group("/api/v1")

	// Auth routes (public)
	authRoutes := v1.Group("/auth")
	{
		authRoutes.POST("/login", container.AuthController.Login)
		authRoutes.POST("/register", container.AuthController.Register)
		authRoutes.POST("/refresh", container.AuthController.RefreshToken)
		authRoutes.POST("/validate", container.AuthController.ValidateToken)
	}

	// Protected routes (require authentication)
	protected := v1.Group("")
	protected.Use(auth.AuthMiddleware(container.AuthService))
	{
		// Auth protected routes
		protected.POST("/auth/logout", container.AuthController.Logout)
		protected.GET("/auth/profile", container.AuthController.GetProfile)
		protected.PUT("/auth/profile", container.AuthController.UpdateProfile)
		protected.PUT("/auth/password", container.AuthController.ChangePassword)

		// Device routes
		deviceRoutes := protected.Group("/devices")
		deviceRoutes.Use(auth.RequirePermission(container.AuthService, "devices", "read"))
		{
			deviceRoutes.GET("", container.DeviceController.ListDevices)
			deviceRoutes.GET("/:id", container.DeviceController.GetDevice)
			deviceRoutes.GET("/:id/shadow", container.DeviceController.GetDeviceShadow)
			deviceRoutes.GET("/:id/credentials", auth.RequirePermission(container.AuthService, "devices", "write"), container.DeviceController.GetDeviceCredentials)
			deviceRoutes.GET("/statistics", container.DeviceController.GetDeviceStatistics)

			// Write operations
			deviceRoutes.POST("", auth.RequirePermission(container.AuthService, "devices", "write"), container.DeviceController.CreateDevice)
			deviceRoutes.PUT("/:id", auth.RequirePermission(container.AuthService, "devices", "write"), container.DeviceController.UpdateDevice)
			deviceRoutes.PUT("/:id/shadow", auth.RequirePermission(container.AuthService, "devices", "write"), container.DeviceController.UpdateDeviceShadow)
			deviceRoutes.PUT("/:id/status/:status", auth.RequirePermission(container.AuthService, "devices", "write"), container.DeviceController.SetDeviceStatus)
			deviceRoutes.POST("/:id/regenerate-secret", auth.RequirePermission(container.AuthService, "devices", "write"), container.DeviceController.RegenerateDeviceSecret)

			// Delete operations
			deviceRoutes.DELETE("/:id", auth.RequirePermission(container.AuthService, "devices", "delete"), container.DeviceController.DeleteDevice)
		}

		// Telemetry routes
		telemetryRoutes := protected.Group("/telemetry")
		telemetryRoutes.Use(auth.RequirePermission(container.AuthService, "telemetry", "read"))
		{
			telemetryRoutes.GET("/:deviceId", container.TelemetryController.GetTelemetryData)
			telemetryRoutes.GET("/:deviceId/latest", container.TelemetryController.GetLatestTelemetryData)
			telemetryRoutes.GET("/:deviceId/aggregated", container.TelemetryController.GetAggregatedData)
			telemetryRoutes.GET("/:deviceId/summary", container.TelemetryController.GetDeviceDataSummary)
			telemetryRoutes.GET("/statistics", container.TelemetryController.GetTelemetryStatistics)

			// Write operations
			telemetryRoutes.POST("", auth.RequirePermission(container.AuthService, "telemetry", "write"), container.TelemetryController.SubmitTelemetryData)
			telemetryRoutes.POST("/batch", auth.RequirePermission(container.AuthService, "telemetry", "write"), container.TelemetryController.SubmitBatchTelemetryData)

			// Delete operations (admin only)
			telemetryRoutes.DELETE("/:deviceId", auth.RequireRole("admin"), container.TelemetryController.DeleteTelemetryData)
		}

		// Commands routes (to be implemented)
		commandRoutes := protected.Group("/commands")
		commandRoutes.Use(auth.RequirePermission(container.AuthService, "commands", "send"))
		{
			// commandRoutes.POST("/:deviceId", container.CommandController.SendCommand)
			// commandRoutes.GET("/:deviceId", container.CommandController.GetCommandHistory)
			// commandRoutes.GET("/:commandId/status", container.CommandController.GetCommandStatus)
		}

		// Rules routes (to be implemented)
		ruleRoutes := protected.Group("/rules")
		ruleRoutes.Use(auth.RequirePermission(container.AuthService, "rules", "read"))
		{
			// ruleRoutes.GET("", container.RuleController.ListRules)
			// ruleRoutes.GET("/:id", container.RuleController.GetRule)
			// ruleRoutes.POST("", auth.RequirePermission(container.AuthService, "rules", "write"), container.RuleController.CreateRule)
			// ruleRoutes.PUT("/:id", auth.RequirePermission(container.AuthService, "rules", "write"), container.RuleController.UpdateRule)
			// ruleRoutes.DELETE("/:id", auth.RequirePermission(container.AuthService, "rules", "delete"), container.RuleController.DeleteRule)
		}

		// Alerts routes (to be implemented)
		alertRoutes := protected.Group("/alerts")
		alertRoutes.Use(auth.RequirePermission(container.AuthService, "alerts", "read"))
		{
			// alertRoutes.GET("", container.AlertController.ListAlerts)
			// alertRoutes.GET("/:id", container.AlertController.GetAlert)
			// alertRoutes.PUT("/:id/acknowledge", container.AlertController.AcknowledgeAlert)
			// alertRoutes.PUT("/:id/resolve", container.AlertController.ResolveAlert)
		}

		// Admin routes
		adminRoutes := protected.Group("/admin")
		adminRoutes.Use(auth.RequireRole("admin"))
		{
			// User management
			userRoutes := adminRoutes.Group("/users")
			{
				// Placeholder endpoints - to be implemented
				userRoutes.GET("", func(c *gin.Context) {
					c.JSON(200, gin.H{"message": "User management endpoint - to be implemented"})
				})
				// userRoutes.GET("/:id", container.UserController.GetUser)
				// userRoutes.PUT("/:id", container.UserController.UpdateUser)
				// userRoutes.DELETE("/:id", container.UserController.DeleteUser)
				// userRoutes.PUT("/:id/roles", container.UserController.UpdateUserRoles)
			}

			// System management
			systemRoutes := adminRoutes.Group("/system")
			{
				// Placeholder endpoints - to be implemented
				systemRoutes.GET("/health", func(c *gin.Context) {
					c.JSON(200, gin.H{"message": "System health endpoint - to be implemented"})
				})
				// systemRoutes.GET("/metrics", container.SystemController.GetSystemMetrics)
				// systemRoutes.POST("/backup", container.SystemController.CreateBackup)
				// systemRoutes.GET("/logs", container.SystemController.GetSystemLogs)
			}
		}
	}

	// Webhook endpoints (external access)
	webhookRoutes := v1.Group("/webhooks")
	{
		// Placeholder endpoint - to be implemented
		webhookRoutes.POST("/:id", func(c *gin.Context) {
			c.JSON(200, gin.H{"message": "Webhook endpoint - to be implemented"})
		})
	}

	// Public API endpoints (with API key authentication)
	publicAPI := v1.Group("/public")
	publicAPI.Use(auth.APIKeyMiddleware(container.AuthService))
	{
		// publicAPI.POST("/telemetry", container.TelemetryController.SubmitTelemetryData)
		// publicAPI.GET("/devices/:id/status", container.DeviceController.GetDeviceStatus)
	}
}
